package br.com.gaspar.utils;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 
 * @author gaspar
 *
 */
public class AnotacaoUtil {
	
	public static final Logger log = LoggerFactory.getLogger(AnotacaoUtil.class);
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Annotation getAnotacao(Object objeto, Class anotacao){
		return objeto.getClass().getAnnotation(anotacao);
	}
	
	/**
	 * Recupera de dentro da anotação @NamedQuery a query correspondente a entidade.
	 * A @NameQuery precisa estar aninhada dentro da anotação @NamedQuerys
	 * @param namedQuery
	 * @param entidade
	 * @return
	 * 
	 * @author gaspar
	 */
	public static String getQueryDeNamedQuery(String namedQuery, Class<?> entidade){
		String hql = "";
		NamedQuery nq = getNamedQuery(namedQuery, entidade);
		if(nq != null){
			hql = nq.query();
		}
		return hql;
	}
	
	/**
	 * Devolve o objeto NamedQuery da entidade passada no parâmetro
	 * @param namedQuery
	 * @param entidade
	 * @return
	 * 
	 * @author gaspar
	 */
	public static NamedQuery getNamedQuery(String namedQuery, Class<?> entidade){
		NamedQuery nq = null;
		NamedQuery[] todasNQ = getTodasNamedQuery(entidade);
		if(todasNQ != null){
			for (NamedQuery item : todasNQ) {
				if(item.name().equals(namedQuery)){
					nq = item;
					break;
				}
			}
		}
		return nq;
	}
	
	public static NamedQuery[] getTodasNamedQuery(Class<?> entidade){
		NamedQuery[] todasNQ = null;
		try{
			NamedQueries querys = (NamedQueries) entidade.getAnnotation(NamedQueries.class);
			if(querys != null){
				todasNQ = querys.value();
			}
		}catch (Exception e) {
			log.error("Erro ao processar anotação!");
		}
		return todasNQ;
	}
	
	/**
	 * Retorna um Array de Strings contendo os nomes das namedQuerys de naoDeveExistir
	 * que a entidade passada no parâmetro possui
	 * @param entidade
	 * @return
	 * @author gaspar
	 */
	public static List<String> getNamedQuerysNaoDeveExistir(Class<?> entidade){
		List<String> nomes = new ArrayList<String>();
		NamedQuery[] todasNQ = getTodasNamedQuery(entidade);
		if(todasNQ != null){
			for (NamedQuery item : todasNQ) {
				Pattern p = Pattern.compile(entidade.getSimpleName() + ".naoDeveExistir");
				Matcher matcher = p.matcher(item.name());
				if(matcher.find()){
					nomes.add(item.name());
				}
			}
		}
		return nomes;
	}

}
